package myjava.l_reflect.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * @Auther: cty
 * @Date: 2020/2/19 17:56
 * @Description: 操作构造器
 * 一、获取类对象
 * 二、获取构造器对象
 *          getConstructors()                     获取 “类” 的 “所有” 构造器       返回Constructor[]
 *          getConstructor(数据类型.class,...)     获取 “类” 的 “指定” 构造器       返回Constructor
 * 三、操作构造器对象（创建实例化对象）
 *          newInstance()                          无参构造器创建实例化对象
 *          newInstance(参数值1,参数值2,...)        有参构造器创建实例化对象
 *
 * @version: 1.0
 */
public class OperateConstructor {
    public static void main(String[] args) {
        TestConstructor();
    }

    // 打印方法对象的修饰符、构造器名、形参
    public static void printInfo(Constructor cs){
        // Method类常用方法
        System.out.println("获取修饰符-->"+cs.getModifiers());  // 每个修饰符对应一个数值，若有多个修饰符则返回数值之和，数值之和不会与修饰符的数值重复
        System.out.println("获取构造器名-->"+cs.getName());  // 返回一个字符串
        System.out.println("获取形参类型：");  // 返回一个class对象数组
        for(int i=0; i<cs.getParameterTypes().length; i++){
            System.out.println(cs.getParameterTypes()[i]);
        }
        System.out.println("-------------------------");
    }

    public static void TestConstructor(){
        try {
            // 一、获取类对象
            Class cla=Class.forName("com.cty.pojo.Student");
            // 二、获取构造器对象
            System.out.println("2-1 获取 “类” 的 “所有” 构造器");
            Constructor[] cs21 = cla.getConstructors();
            for(Constructor c:cs21){
                printInfo(c);
            }
            System.out.println("**********************************************************");

            System.out.println("2-2 获取 “类” 的 “指定” 构造器");
            Constructor c21 = cla.getConstructor();
            Constructor c22 = cla.getConstructor(String.class, String.class, String.class, int.class, boolean.class);
            System.out.println("**********************************************************");

            // 三、操作构造器对象（创建实例化对象）
            System.out.println("3-1 无参构造器创建实例化对象");
            Object obj31 = c21.newInstance();
            if((boolean)cla.getDeclaredField("isStudyWell").get(obj31)){
                System.out.println("我学习成绩不错。");
            }else {
                System.out.println("我学习成绩还有待提升。");
            }
            System.out.println("**********************************************************");

            System.out.println("3-2 有参构造器创建实例化对象");
            Object obj32 = c22.newInstance("张三","00001", "高三2班", 1, true);
            System.out.println(cla.getDeclaredMethod("information").invoke(obj32,null));
            System.out.println("**********************************************************");

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
}

/* res:
2-1 获取 “类” 的 “所有” 构造器
获取修饰符-->1
获取构造器名-->com.cty.pojo.Student
获取形参类型：
-------------------------
获取修饰符-->1
获取构造器名-->com.cty.pojo.Student
获取形参类型：
class java.lang.String
class java.lang.String
class java.lang.String
int
boolean
-------------------------
**********************************************************
2-2 获取 “类” 的 “指定” 构造器
**********************************************************
3-1 无参构造器创建实例化对象
我学习成绩不错。
**********************************************************
3-2 有参构造器创建实例化对象
我叫张三，我的学号是00001，我在高三2班1组。
另外，偷偷告诉你，我早恋了。
null  【为啥出现个null？？？】
**********************************************************
*/